from django.core.paginator import Paginator, EmptyPage
from django.shortcuts import render
from django.utils import timezone
from django.views import View
from django import http

from contents.utils import get_categories
from goods.models import GoodsCategory, SKU
from goods.models import GoodsVisitCount
from goods.utils import get_breadcrumb
from meiduo_mall.utils.response_code import RETCODE
from datetime import datetime


class DetailVisitView(View):
    def post(self, request, category_id):
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('category_id 不存在')

        # 获取当天日期:localdate()
        # t = timezone.localtime()
        today_date = timezone.localdate()
        # 获取当天时间字符串
        # today_str = '%d-%02d-%02d' % (t.year, t.month, t.day)
        # # datetime.strftime() 时间对象转时间字符串
        # today_date = datetime.strptime(today_str, '%Y-%m-%d')  # 时间字符串转时间对象
        try:
            counts_data = GoodsVisitCount.objects.get(date=today_date, category=category)
        except GoodsVisitCount.DoesNotExist:
            counts_data = GoodsVisitCount()

        try:
            counts_data.category = category
            counts_data.count += 1
            counts_data.date = today_date
            counts_data.save()
        except Exception as e:
            return http.HttpResponseServerError('统计失败')
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})


class DetailView(View):
    """商品详情"""
    def get(self, request, sku_id):
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoseNotExist:
            return render(request, '404.html')

        # 查询商品分类
        categories = get_categories()

        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        sku_specs = sku.specs.order_by('spec_id')
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()
        # 构建不同规格参数的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_spus = s.specs.order_by('spec_id')
            key = []
            for spec in s_spus:
                key.append(spec.option.id)
            spec_sku_map[tuple(key)] = s.id
        #  获取当期商品的规格信息
        goods_specs = sku.spu.specs.order_by('id')
        #  若规格不完整，则不再继续
        if len(sku_key) < len(goods_specs):
            return
        for index, spec in enumerate(goods_specs):
            # 复制当前sku规格键
            key = sku_key[:]
            # 该规格的选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index] = option.id
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options

        #  构造上下文
        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
            'spec': goods_specs,
        }

        return render(request, 'detail.html', context)


class HotGoodsView(View):
    """热销排行"""
    def get(self, request, category_id):
        #  查询指定分类的SKU信息，且上架，按销量由高到低，切片取出前两位
        skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]
        #  将模型列表转字典列表，构造JSON数据
        hot_skus = []
        for sku in skus:
            sku_dict = {
                'id': sku.id,
                'name': sku.name,
                'price': sku.price,
                'default_image_url': sku.default_image.url,
            }
            hot_skus.append(sku_dict)

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})


class ListView(View):
    """商品列表页"""
    def get(self, request, category_id, page_num):
        """查询并渲染商品列表页"""
        #  校验参数category_id的范围： 111111111111111111
        try:
            #  三级类别
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoseNotExist:
            return http.HttpResponseForbidden('参数category_id不存在')

        #  获取sort(排序规则)：若sort没值，取‘default’
        sort = request.GET.get('sort', 'default')
        #  根据sort选择排序字段，且字段必须是模型类的属性
        if sort == 'price':  #  按价格由低到高排序
            sort_field = 'price'
        elif sort == 'hot':  #  按销量由低到高排序
            sort_field = '-sales'
        else:  #  只要不是price和sales，其他情况均归为default
            sort = 'default' #  当出现其他错误情况，也把sort设置为default
            sort_field = 'create_time'

        #  查询商品分类
        categories = get_categories()

        #  查询面包屑导航 一级 > 二级 > 三级
        breadcrumb = get_breadcrumb(category)

        #  分页和排序查询：category查询sku,一查多，
        # skus = SKU.objects.filter(category=category, is_launched=True)   无经验查询方式
        skus = category.sku_set.filter(is_launched=True).order_by(sort_field)

        #  创建分页器
        #  Paginator(分页内容， 每页条数)
        paginator = Paginator(skus, 5)
        try:
            #  获取用户当前要看的页面（核心数据）
            page_skus = paginator.page(page_num)
        except EmptyPage:
            return http.HttpResponseNotFound('empty page')
        #  获取总页数，前端分页插件要用
        total_page = paginator.num_pages

        #  构造上下文
        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'page_skus': page_skus,
            'total_page': total_page,
            'page_num': page_num,
            'sort': sort,
            'category_id': category_id,
        }

        return render(request, 'list.html', context)




